import store from "../store";
import {commonConfig, momentFormat} from "@/config/common";
import {tableIdMap, tableOptBtnConfig} from "@/config/table";
import {getStorage, StorageKey} from "@/config/sessions";

export class TableStateHdl {
  constructor(routeName = "", tableId = "", columnConfig = [], filterConfig = []) {
    this.routeName = routeName;
    this.tableId = tableId;
    this.paramKey = {};
    this.paramState = {};
    this.tableConfig = filterConfig;
    this.columnConfig = columnConfig;
    this.filterConfig = []; // 筛选条件
    this.searchConfig = []; // 搜索条件
    this.pageNo = 1;
    this.pageSize = commonConfig.defaultPageSize;
    this.total = 0;
    this.sortResult = [];
    this.filterResult = {}; // 已筛选的条件
    this.searchResult = {}; // 已搜索的条件
    this.filters = []; // 用于存放所有提交后台接口的筛选、搜索项
    this.initData();
  }

  initData() { // 初始化数据
    const mapStr = tableIdMap[this.tableId]; // tableId映射
    this.paramKey = {
      pageNo: `${mapStr}_pageNo`,
      pageSize: `${mapStr}_pageSize`,
      sort: `${mapStr}_sort`,
      filter: `${mapStr}_filter`,
      search: `${mapStr}_search`, // 映射后的搜索参数键名
    };
    this.initFilterSearchConfig();
    this.initTableParam();
  }

  initFilterSearchConfig() { // 初始化筛选搜索配置
    const filterResult = {};
    const searchResult = {};
    this.filterConfig = [];
    this.searchConfig = [];
    this.tableConfig.forEach((config) => {
      const {fieldType, key, dataApi} = config;
      switch (fieldType) {
        case "input":
          searchResult[key] = []; // 清空已搜索条件对象中的值
          this.searchConfig.push(config);
          break;
        case "string":
        case "bool":
        case "cascade":
          filterResult[key] = []; // 清空已筛选条件对象中的值
          this.getOptionData(dataApi, config);
          break;
        case "year":
        case "date":
          filterResult[key] = [];
          this.filterConfig.push(config);
          break;
        case "number":
        case "daterange":
        case "datetimerange":
        case "datetime":
          filterResult[key] = {begin: "", end: ""};
          this.filterConfig.push(config);
          break;
        default:
          break;
      }
    });
    this.filterResult = filterResult;
    this.searchResult = searchResult;
  }

  // 获取筛选数据源
  getOptionData(dataApi, config = {}) {
    if (!dataApi) return this.filterConfig.push(config);
    dataApi().then((resp) => {
      const {data = []} = resp;
      config.options = data.map(d => {
        return {label: d.label, value: d.value};
      });
      // this.filterConfig.push(config);
    }).catch((err) => {
      console.log('err', err);
      this.filterConfig.push(config);
    });
    this.filterConfig.push(config);
  }

  // 初始化表格参数
  initTableParam() {
    const {routeParamState} = store.state.routeParam;
    this.paramState = routeParamState[this.routeName] || {};
    const pageNo = this.paramState[this.paramKey.pageNo] || 1;
    const pageSize = this.paramState[this.paramKey.pageSize] || commonConfig.defaultPageSize;
    this.pageNo = parseInt(pageNo);
    this.pageSize = parseInt(pageSize);
    this.sortResult = this.paramState[this.paramKey.sort] || [];
    this.filterResult = this.paramState[this.paramKey.filter] || {};
    this.searchResult = this.paramState[this.paramKey.search] || {};
  }

  // 更新表格参数
  updateTableParam(value = {}) {
    const destValue = {};
    Object.keys(value).forEach((key) => {
      // 遍历value对象的键
      const val = value[key];
      destValue[this.paramKey[key]] = value[key];
      switch (key) {
        case "pageNo":
          this.pageNo = val || 1;
          break;
        case "pageSize":
          this.pageSize = val || commonConfig.defaultPageSize;
          break;
        case "sort":
          this.sortResult = val || [];
          break;
        case "filter":
        case "search":
          break;
        default:
          break;
      }
    });
    updateRouteParamState(this.routeName, destValue);
  }

  // 组装 table 接口参数
  assembleTableParam() {
    this.assembleTableFilters();
    return {
      pageNo: this.pageNo,
      pageSize: this.pageSize,
      filters: this.filters,
      sort: this.sortResult
    };
  }

  assembleTableFilters() {
    const filters = []; // 将 filterResult searchResult 组装成数组
    Object.keys(this.filterResult).forEach(key => {
      // 遍历集合中的每个属性，拿到筛选搜索配置
      const config = this.tableConfig.find(cfg => cfg.fieldType === 'string' && cfg.key === key);
      if (!config) return;
      const {fieldType} = config;
      const value = this.filterResult[key];
      switch (fieldType) {
        case "string":
        case "bool":
        case "cascade":
          // 值不为空时，filters添加对应的筛选搜索条件
          value.length > 0 && filters.push({key, fieldType, value: value});
          break;
        case "number":
        case "daterange":
        case "datetimerange":
        case "datetime":
          const {begin, end} = value || {};
          if (begin || end) {
            const filter = {key, fieldType};
            begin && (filter.begin = begin);
            end && (filter.end = end);
            filters.push(filter);
          }
          break;
        default:
          break;
      }
    });
    Object.keys(this.searchResult).forEach(key => {
      const config = this.tableConfig.find(cfg => cfg.fieldType === 'input' && cfg.key === key);
      if (!config) return;
      const {fieldType} = config;
      const value = this.searchResult[key];
      value.length > 0 && filters.push({key, fieldType, value: value});
    });
    this.filters = filters;
  }

  // 当删除 table row 后，判断 table 的 total、pageSize、pageNo 是否匹配
  judgeTableMatched() {
    const lastPage = Math.ceil((this.total - 1) / this.pageSize);
    if (this.pageNo > lastPage) {
      this.updateTableParam({pageNo: lastPage});
    }
  }

  // 清空 table 参数
  clearTableParam() {
    this.pageNo = 1;
    this.pageSize = commonConfig.defaultPageSize;
    this.sortResult = [];
    this.filterResult = {};
    this.searchResult = {};
    updateRouteParamState(this.routeName, {
      [this.paramKey.pageNo]: 1,
      [this.paramKey.pageSize]: commonConfig.defaultPageSize,
      [this.paramKey.sort]: [],
      [this.paramKey.filter]: {},
      [this.paramKey.search]: {},
    });
  }
}

// 根据 routeName 更新 store 中的 routeParamState
export function updateRouteParamState(routeName = "", data = {}) {
  if (!routeName) return;
  const {routeParamState} = store.state.routeParam;
  if (!routeParamState || !routeParamState[routeName]) return;
  const state = routeParamState[routeName];
  store.dispatch("updateRouteParamState", {
    route: routeName,
    ...state,
    ...data,
  }).then(() => {
  });
}

// 组装 table opt btn 数据，添加 callback、根据 type 来确定 label
export function assembleTableOptBtn(src = [], callback) {
  const operation = src.find((s) => {
    return s["operation"] === true; // 返回列配置中的operation为true的元素
  });
  if (!operation) return;
  const getBtnLabel = (opt = {}) => {
    const {type = "", label = ""} = opt;
    if (label) return label;
    if (type && tableOptBtnConfig[type]) {
      return tableOptBtnConfig[type].label; // 按钮类型存在且表格按钮配置存在该按钮类型=>返回当前按钮的label
    } else {
      return "";
    }
  };
  operation["horizontal"] = true;
  const {children = []} = operation;
  children.forEach((child) => {
    child["callback"] = callback;
    if (child.button) {
      child.label = getBtnLabel(child); // 是按钮=>获取按钮label
    } else if (child.dropdown) {
      const {options = []} = child;
      options.forEach((opt) => {
        opt.label = getBtnLabel(opt); // 是下拉菜单=>获取每个选项的label
      });
    }
  });
}

// 过滤出不需要返回的 columns
function ignoreColumns(src = [], ignore = []) {
  const dest = []; // 存储需要返回的列配置
  src.forEach((c) => {
    // 遍历列配置的每一项
    if (!ignore.includes(c.label)) {
      // 需要隐藏的列配置不包含当前项的key时添加
      dest.push({
        hide: false,
        checkable: false,
        ...c,
      });
    }
  });
  return dest; // 返回需要显示的列配置
}

// 过滤不需要返回的 filters
function ignoreFilters(src = [], ignore = []) {
  const dest = []; // 存储需要返回的筛选配置
  src.forEach((c) => {
    // 遍历筛选配置的每一项
    if (!ignore.includes(c.key)) {
      // 不需要返回的筛选配置不包含当前项的key时添加
      dest.push(c);
    }
  });
  return dest; // 返回需要返回的筛选配置
}

// 通过 tableId 接口获取该 table 的 column、filter 配置
export function getTableConfig(tableId = "", tableCfg = {}, ignoreColumn = [], ignoreFilter = []) {
  if (!tableId) return {
    columns: [],
    filters: [],
  };
  const {filters = [], columns = []} = tableCfg;
  return {
    columns: ignoreColumns(columns, ignoreColumn),
    filters: ignoreFilters(filters, ignoreFilter),
  };
}
